/*   
 * Copyright (c) 2010-2020 DMGIS Ltd. All Rights Reserved.   
 *   
 * This software is the confidential and proprietary information of   
 * DMGIS. You shall not disclose such Confidential Information   
 * and shall use it only in accordance with the terms of the agreements   
 * you entered into with DMGIS.   
 *   
 */
package com.dmgis.qxfw.dataservice.businessservice.dmgis_mongodb_srv.common.util;

import org.bson.Document;

import java.io.*;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * This class is used for 文件操作类
 * 
 * @author dsq
 * @version 1.0, 2018年7月7日 下午4:03:35
 */
public class FileUtil {

	/**
	 * 写入文件，末尾自动添加\r\n
	 * 
	 * @param path
	 * @param str
	 * @author dsq
	 * @date 2018年7月7日
	 */
	public static void writeLog(String path, String str) {
		try {
			File file = new File(path);
			if (!file.exists()) {
				file.createNewFile();
			}
			FileOutputStream out = new FileOutputStream(file);
			StringBuffer sBuffer = new StringBuffer();
			sBuffer.append(str + "\r\n");
			out.write(sBuffer.toString().getBytes("uft-8"));
			out.close();
		} catch (Exception e) {
			// TODO: 文件写入异常
			System.out.println(e.getStackTrace());
		}
	}

	/**
	 * 
	 * @param path
	 * @param str
	 * @param is_append
	 * @param encode
	 * @author dsq
	 * @date 2018年7月7日
	 */
	public static void writeLog(String path, String str, boolean is_append, String encode) {
		try {
			File file = new File(path);
			if (!file.exists()) {
				file.createNewFile();
			}
			FileOutputStream out = new FileOutputStream(file, is_append);// true表示追加，否则表示新建
			StringBuffer sBuffer = new StringBuffer();
			sBuffer.append(str + "\r\n");
			out.write(sBuffer.toString().getBytes("uft-8"));
			out.close();
		} catch (IOException e) {
			// TODO: 文件写入异常
			System.out.println(e.getStackTrace());
		}
	}

	/**
	 * 整个文件以string返回，添加换行
	 * 
	 * @param path
	 * @return
	 * @author dsq
	 * @date 2018年7月7日
	 */
	public static String readLogByString(String path) {
		StringBuffer sb = new StringBuffer();
		String tempstr = null;
		try {
			File file = new File(path);
			if (!file.exists())
				throw new FileNotFoundException();
			FileInputStream fis = new FileInputStream(file);
			BufferedReader br = new BufferedReader(new InputStreamReader(fis, "utf-8"));
			while ((tempstr = br.readLine()) != null) {
				sb.append(tempstr + "\r\n");
			}
			br.close();
		} catch (IOException ex) {
			// TODO: 文件读取异常
			System.out.println(ex.getStackTrace());
		}
		return sb.toString();
	}

	/**
	 * 按照制定编码返回结果
	 * 
	 * @param path
	 * @param encode
	 * @return
	 * @author dsq
	 * @date 2018年7月7日
	 */
	public static String readLogByStringAndEncode(String path, String encode) {
		StringBuffer sb = new StringBuffer();
		String tempstr = new String();
		try {
			File file = new File(path);
			if (!file.exists())
				throw new FileNotFoundException();
			FileInputStream fis = new FileInputStream(file);
			BufferedReader br = new BufferedReader(new InputStreamReader(fis, encode));
			while ((tempstr = br.readLine()) != null) {
				sb.append(tempstr + "\r\n");
			}
			br.close();
		} catch (IOException e) {
			// TODO: 文件读取异常
			System.out.println(e.getStackTrace());
		}
		return sb.toString();
	}

	/**
	 * 按行读取文件，以List返回
	 * 
	 * @param path
	 * @return
	 * @author dsq
	 * @date 2018年7月7日
	 */
	public static List<String> readLogByList(String path) {
		List<String> lines = new ArrayList<String>();
		String tempstr = null;
		try {
			File file = new File(path);
			if (!file.exists())
				throw new FileNotFoundException();
			FileInputStream fis = new FileInputStream(file);
			BufferedReader br = new BufferedReader(new InputStreamReader(fis, "utf-8"));
			while ((tempstr = br.readLine()) != null) {
				lines.add(tempstr);
			}
			br.close();
		} catch (IOException e) {
			// TODO: 文件读取异常
			System.out.println(e.getStackTrace());
		}
		return lines;
	}

	/**
	 * 二进制json文件读取
	 * 
	 * @param path
	 * @return
	 * @author dsq
	 * @date 2018年7月7日
	 */
	public static List<Document> readDocsFromFile(String path) {
		List<String> str_docs = readLogByList(path);
		List<Document> docs = new ArrayList<Document>();
		// System.out.println(str_docs.size());
		for (int i = 0; i < str_docs.size(); i++) {
			String str_doc = str_docs.get(i);
			// System.out.println(str_doc);
			Document doc = null;
			try {
				doc = Document.parse(str_doc);
			} catch (Exception e) {
				// TODO: 文件读取异常
				System.out.println("\nreadDocsFromFile 中异常, 文件:" + path + "\n第" + i + "行,\n" + str_doc);
			}
			if (null != doc) {
				docs.add(doc);
			}
		}
		return docs;
	}

	/**
	 * 创建多级目录 mkdir创建一级目录 mkdirs创建多级目录
	 * 
	 * @param dir_path
	 * @author dsq
	 * @date 2018年7月7日
	 */
	public static void mkDirs(String dir_path) {
		File myFolderFile = new File(dir_path);
		try {
			if (!myFolderFile.exists()) {
				myFolderFile.mkdirs();
			}
		} catch (Exception e) {
			// TODO: 创建目录出错
			System.out.println(e.getStackTrace());
		}
	}

	/**
	 * 创建文件
	 * 
	 * @param file_path
	 * @author dsq
	 * @date 2018年7月7日
	 */
	public static void createNewFile(String file_path) {
		File myFilePathFile = new File(file_path);
		try {
			myFilePathFile.createNewFile();// 创建文件
		} catch (Exception e) {
			// TODO: 创建文件出错
			System.out.println(e.getStackTrace());
		}
	}

	/**
	 * 删除文件加下的所有文件
	 * 
	 * @param file_path
	 * @author dsq
	 * @date 2018年7月7日
	 */
	public static void deleteFolder(String file_path) {
		try {
			File file = new File(file_path);
			if (!file.exists()) {
				return;
			}
			if (file.isFile()) {
				file.delete();
			} else {
				File[] files = file.listFiles();
				for (int i = 0; i < files.length; i++) {
					String root = files[i].getAbsolutePath();
					deleteFolder(root);
				}
				file.delete();
			}
		} catch (Exception e) {
			// TODO: 删除文件失败
			System.out.println(e.getStackTrace());
		}
	}

	/**
	 * 得到一个文件夹下的所有文件
	 * 
	 * @param fold_path
	 * @return
	 * @author dsq
	 * @date 2018年7月7日
	 */
	public static List<String> getAllFileNameInFold(String fold_path) {
		List<String> file_paths = new ArrayList<String>();

		LinkedList<String> folderList = new LinkedList<String>();
		folderList.add(fold_path);
		while (folderList.size() > 0) {
			File file = new File(folderList.peekLast());
			folderList.removeLast();
			File[] files = file.listFiles();
			ArrayList<File> fileList = new ArrayList<File>();
			for (int i = 0; i < files.length; i++) {
				if (files[i].isDirectory()) {
					folderList.add(files[i].getPath());
				} else {
					fileList.add(files[i]);
				}
			}
			for (File f : fileList) {
				file_paths.add(f.getAbsoluteFile().getPath());
			}
		}
		return file_paths;
	}

	/**
	 * 使用FileChannel复制
	 * 
	 * @param source
	 * @param dest
	 * @throws IOException
	 * @author dsq
	 * @date 2018年7月7日
	 */
	@SuppressWarnings("resource")
	public static void copyFileUsingFileChannels(File source, File dest) throws IOException {
		FileChannel inputChannel = null;
		FileChannel outputChannel = null;
		try {
			inputChannel = new FileInputStream(source).getChannel();
			outputChannel = new FileOutputStream(dest).getChannel();
			outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
		} catch (Exception e) {
			// TODO: handle exception
			System.out.println(e.getStackTrace());
		} finally {
			inputChannel.close();
			outputChannel.close();
		}
	}

	/**
	 * 将共享文件保存到本地
	 * 
	 * @param subPath
	 * @param localPath
	 * @author dsq
	 * @date 2018年7月18日
	 */
	public static void copyFromSmb(String subPath, String localPath) {

	}

	/**
	 * 清除临时文件夹中的内容
	 * 
	 * @param floderPath
	 *            文件夹位置
	 * @param maxCache
	 *            数量
	 * @author dsq
	 * @date 2018年7月9日
	 */
	public static void ClearTempFiles(String floderPath, int maxCache) {
		int count = getAllFileNameInFold(floderPath).size();
		if (count > maxCache) {
			deleteFolder(floderPath);
			mkDirs(floderPath);// 建立目录
		}
	}

	public static void ChangeFileEncode(String filename, String orignEncode, String targetEncode) throws IOException {
		File file = new File(filename);
		if (filename.endsWith(".java") & file.isFile()) {
			String[] s = filename.split("\\.");
			String filecope = s[0] + "cope." + s[1];
			System.out.println(filecope);
			File fil = new File(filecope);
			// 转格式，不能一行一行的读取，只能逐个字符的读取
			InputStreamReader isr = new InputStreamReader(new FileInputStream(file), orignEncode);
			OutputStreamWriter osr = new OutputStreamWriter(new FileOutputStream(fil), targetEncode);
			int re = -1;
			while ((re = isr.read()) != -1) {
				osr.write(re);
			}
			isr.close();
			osr.close();
			InputStreamReader isrr = new InputStreamReader(new FileInputStream(fil), targetEncode);
			OutputStreamWriter osrw = new OutputStreamWriter(new FileOutputStream(file), targetEncode);
			int r = -1;
			while ((r = isrr.read()) != -1) {
				osrw.write(r);
			}
			isrr.close();
			osrw.close();
			boolean d = fil.delete();
			System.out.println(filename + "文件转换utf-8成功:" + d);
		}
	}

	/**
	 * 文件转换成bytes
	 * 
	 * @param filePath
	 * @return
	 * @author dsq
	 * @date 2018年8月16日
	 */
	public static byte[] fileToBytes(String filePath) {
		byte[] buffer = null;
		File file = new File(filePath);

		FileInputStream fis = null;
		ByteArrayOutputStream bos = null;

		try {
			fis = new FileInputStream(file);
			bos = new ByteArrayOutputStream();

			byte[] b = new byte[1024];

			int n;

			while ((n = fis.read(b)) != -1) {
				bos.write(b, 0, n);
			}

			buffer = bos.toByteArray();
		} catch (FileNotFoundException ex) {
			ex.printStackTrace();
		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			try {
				if (null != bos) {
					bos.close();
				}
			} catch (IOException ex) {
				ex.printStackTrace();
			} finally {
				try {
					if (null != fis) {
						fis.close();
					}
				} catch (IOException ex) {
					ex.printStackTrace();
				}
			}
		}

		return buffer;
	}

	/**  
	 * bytes转文件
	 * @param buffer
	 * @param filePath  
	 * @author dsq
	 * @date 2018年8月16日
	 */   
	public static void bytesToFile(byte[] buffer, final String filePath) {

		File file = new File(filePath);

		OutputStream output = null;
		BufferedOutputStream bufferedOutput = null;

		try {
			output = new FileOutputStream(file);

			bufferedOutput = new BufferedOutputStream(output);

			bufferedOutput.write(buffer);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (null != bufferedOutput) {
				try {
					bufferedOutput.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			if (null != output) {
				try {
					output.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}
}